<?php

declare(strict_types=1);

namespace App\Job;

use Hyperf\AsyncQueue\Job;
use App\Common\RedisCache;
use App\Exception\NullReturnException;
use App\Model\PlatformSetting;
use Hyperf\DbConnection\Db;

require_once BASE_PATH . '/vendor/alipay-sdk/AopCertClient.php';
require_once BASE_PATH . '/vendor/alipay-sdk/request/AlipayFundTransUniTransferRequest.php';

class AlipayPaymentJob extends Job
{
    public $params;

    public function __construct($params)
    {
        $this->params = $params;
    }

    public function handle()
    {
        $redisCache = new RedisCache();
        // 查询平台设置
        $platSetting = $redisCache->getPlatformSetting();
        // 查询用户代付设置
        $daifuSetting = $redisCache->getDaifuSettingByIdRealTime((int) $this->params['uid']);
        if ($daifuSetting['status'] == 2) {
            $this->notice('您的代付金额处于冻结状态，暂时无法进行支付操作。');
            throw new NullReturnException;
        } else if ($daifuSetting['status'] == -1) {
            $this->notice('您当前暂时无法使用代付功能。');
            throw new NullReturnException;
        }
        if ($platSetting['daifu_out_limit'] == 1) {
            $this->notice('单日最多可转100万元');
            throw new NullReturnException;
        }
        // 校验保证金机制
        if (!isset($daifuSetting['deposit_version_id']) || $daifuSetting['deposit_version_id'] == 0) {
            $this->notice('根据监管部门要求，使用本功能前需缴纳保证金，请先在“代付管理”-“代付设置“-“缴纳保证金”后使用，感谢您的支持');
            throw new NullReturnException;
        }
        $version = Db::table('dpay_deposit_version')->where('id', $daifuSetting['deposit_version_id'])->first();
        $depositInfo = Db::table('deposit')->where('uid', $this->params['uid'])->where('type', 2)->first();
        $version = json_decode(json_encode($version), true);
        $depositInfo = json_decode(json_encode($depositInfo), true);
        if (empty($version)) {
            $this->notice('保证金类别异常或非法，操作中断，如有疑问，可咨询平台客服');
            throw new NullReturnException;
        }
        if (empty($depositInfo)) {
            $this->notice('用户保证金类别异常或非法，操作中断，如有疑问，可咨询平台客服');
            throw new NullReturnException;
        }
        if ($version['money'] > $depositInfo['deposit']) {
            $this->notice('保证金不足，请续交保证金后使用，感谢您的支持');
            throw new NullReturnException;
        }
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['status'] = 1;
        $total_today_pay_money = mongodb()->sum('df_trade_orders', 'money', $where);
        if ($version['limit'] < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过代付保证金对应限额，请调整代付保证金后重试');
            throw new NullReturnException;
        }
        // 计算代付服务费
        $daifuFee = 0;
        $add_feilv = 0;
        // 如果用户设置了费率增浮
        if (isset($this->params['daifu_fee_bili']) && $this->params['daifu_fee_bili'] > 0) {
            $add_feilv = $this->params['daifu_fee_bili'];
        }
        if ($this->params['uid'] != 1) {
            if ($this->params['rank'] == 1) {
                if ($platSetting['daifufree_feilv'] > 0) {
                    $daifuFee = round(($platSetting['daifufree_feilv'] + $add_feilv) * $this->params['money'] / 100, 2);
                    if ($daifuFee < 0.01) {
                        $daifuFee = 0.01;
                    }
                }
                $dailyLimit = (!empty($platSetting['daifu_free_limit'])) ? $platSetting['daifu_free_limit'] : 500;
            } else {
                if ($platSetting['daifufee_feilv'] > 0) {
                    $daifuFee = round(($platSetting['daifufee_feilv'] + $add_feilv) * $this->params['money'] / 100, 2);
                    if ($daifuFee < 0.01) {
                        $daifuFee = 0.01;
                    }
                }
                $dailyLimit = (!empty($platSetting['daifu_fee_limit'])) ? $platSetting['daifu_fee_limit'] : 500;
            }
        }else{
            $dailyLimit = 999999;
        }
        $this_money = round($this->params['money'] + $daifuFee, 2);
        $pay_yue = round($daifuSetting['daifu_money'] - $this_money, 2);
        if (empty($daifuSetting['daifu_money']) || ($pay_yue < $platSetting['daifu_baoliu'])) {
            $this->notice('代付余额(支付后余额)低于' . $platSetting['daifu_baoliu'] . '元将无法使用代付功能，请先登录会员中心进行充值');
            throw new NullReturnException;
        }
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['status'] = 1;
        $total_today_pay_money = mongodb()->sum('df_trade_orders', 'money', $where);
        if ($daifuSetting['max_daily'] < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过您所设置的当日限额，本次代付失败');
            throw new NullReturnException;
        }
        if ($dailyLimit < ($total_today_pay_money + $this->params['money'])) {
            $this->notice('当日代付总金额超过平台系统限制，本次代付失败');
            throw new NullReturnException;
        }
        unset($where);
        // 支付总金额判断
        $where['uid'] = (int) $this->params['uid'];
        $todayStart = strtotime(date('Y-m-d'));
        $todayEnd = strtotime(date('Y-m-d') . ' 23:59:59');
        $where['create_time'] = ['between', [$todayStart, $todayEnd]];
        $where['alipay'] = $this->params['alipay'];
        $where['status'] = 1;
        $total_bishu = mongodb()->count('df_trade_orders', $where);
        if ($daifuSetting['bishu_daily'] <= $total_bishu) {
            $this->notice('该支付宝账户当日代付笔数超过系统当日笔数限额，本次代付失败');
            throw new NullReturnException;
        }
        // 代付支付宝每日限额判断
        $total_money = $redisCache->getDaifuTotalMoneyRealTime();
        if (!empty($platSetting['daifu_qiankuan']) && (round($total_money - $this_money, 2) < $platSetting['daifu_qiankuan'])) {
            (new \App\Service\ClearRedisCache())->clearPlatformSetting();
            $update['daifu_out_limit'] = 1;
            PlatformSetting::query()->where('id', 1)->update($update);
            unset($update);
            $msg = '单日最多可转100万元';
            $updatePayData['async_status'] = -1;
            $updatePayData['status'] = -1;
            $updatePayData['alipay_orderid'] = '';
            $updatePayData['daifu_fee'] = '';
            $updatePayData['daifued_yue'] = '';
            $updatePayData['statusmsg'] = $msg;
            mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
            if (!empty($daifuSetting['async_url'])) {
                $postData['thirdorder'] = $this->params['thirdorder'];
                $postData['orderId'] = $this->params['orderId'];
                $postData['alipay_orderid'] = '';
                $postData['reason'] = $msg;
                $postData['url'] = $daifuSetting['async_url'];
                queue_push(new PaymentResultNoticeJob($postData));
            }
            throw new NullReturnException;
        }
        // 查询支付配置
        $paySetting = $redisCache->getPaySettingById(7);
        if (!empty($daifuSetting['daifuer']) && ($daifuSetting['daifuer_status'] == 2)) {
            $daifuEr = $daifuSetting['daifuer'];
        } else {
            $daifuEr = $this->platformSetting['daifuer'];
        }
        if (!empty($paySetting)) {
            $businessParams = [];
            switch ($this->params['product_code']) {
                case 'redPacket':
                    $code = 'STD_RED_PACKET';
                    $businessParams['sub_biz_scene'] = 'REDPACKET';
                    break;
                case 'alipay':
                    $code = 'TRANS_ACCOUNT_NO_PWD';
                    break;
                case 'bank':
                    $code = 'TRANS_BANKCARD_NO_PWD';
                    $businessParams['withdraw_timeliness'] = 'T0';
                    break;
                default:
                    $code = 'TRANS_ACCOUNT_NO_PWD';
                    break;
            }
            $aop = new \AopCertClient();
            $appCertPath = BASE_PATH.'/cert/2018112462287537/appCertPublicKey_2018112462287537.crt';
            $alipayCertPath = BASE_PATH.'/cert/2018112462287537/alipayCertPublicKey_RSA2.crt';
            $rootCertPath = BASE_PATH.'/cert/2018112462287537/alipayRootCert.crt';

            $aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
            $aop->appId = '2018112462287537';
            $aop->rsaPrivateKey = $paySetting['merchant_private_key'];
            $aop->appCertSN = $aop->getCertSN($appCertPath);
            $aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);
            $aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
            $aop->isCheckAlipayPublicCert = true;
            $aop->signType = 'RSA2';
            $aop->charset = 'UTF-8';
            $aop->format = 'json';
            $alipayRequest = new \AlipayFundTransUniTransferRequest();
            $conAr['out_biz_no'] = $this->params['orderId'];
            $conAr['trans_amount'] = $this->params['money'];
            $conAr['product_code'] = $code;
            $conAr['order_title'] = $daifuEr;
            $conAr['biz_scene'] = 'DIRECT_TRANSFER';
            $conAr['payee_info']['identity'] = $this->params['alipay'];
            $conAr['payee_info']['name'] = $this->params['realname'];
            $conAr['payee_info']['identity_type'] = 'ALIPAY_LOGON_ID';
            $conAr['remark'] = $this->params['beizhu'];
            if (!empty($businessParams)) {
                $conAr['business_params'] = $businessParams;
            }
            $alipayRequest->setBizContent(json_encode($conAr));
            Db::beginTransaction();
            $feeStatus = Db::table('daifu_setting')->where('uid', $this->params['uid'])->decrement('daifu_money', $this_money);
            $daifuSetting = $redisCache->getDaifuSettingByIdRealTime((int) $this->params['uid']);
            if ($daifuSetting['daifu_money'] <= $platSetting['daifu_baoliu']) {
                Db::rollBack();
                $msg = '代付余额(支付后余额)低于' . $platSetting['daifu_baoliu'] . '元将无法使用代付功能，请先登录会员中心进行充值';
                $updatePayData['status'] = -1;
                $updatePayData['statusmsg'] = $msg;
                $updatePayData['daifued_yue'] = $pay_yue;
                mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
                if (!empty($daifuSetting['async_url'])) {
                    // $postData['event'] = 'PAYMENT_FAIL';
                    $postData['thirdorder'] = $this->params['thirdorder'];
                    $postData['orderId'] = $this->params['orderId'];
                    $postData['alipay_orderid'] = '';
                    $postData['reason'] = $msg;
                    $postData['url'] = $daifuSetting['async_url'];
                    queue_push(new PaymentResultNoticeJob($postData));
                }
                throw new NullReturnException;
            }
            $result = $aop->execute($alipayRequest);
            $responseNode = str_replace(".", "_", $alipayRequest->getApiMethodName()) . "_response";
            $resultCode = $result->$responseNode->code;
            if (!empty($resultCode) && ($resultCode == 10000 || $resultCode == '10000')) {
                Db::commit();
                $order_id = $result->$responseNode->order_id;
                $updatePayData['alipay_orderid'] = $order_id;
                $updatePayData['status'] = 1;
                $updatePayData['daifued_yue'] = $pay_yue;
                $updatePayData['daifu_fee'] = round($daifuFee, 2);
                mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
                if (!empty($daifuSetting['async_url'])) {
                    $postData['result'] = 'ok';
                    $postData['thirdorder'] = $this->params['thirdorder'];
                    $postData['orderId'] = $this->params['orderId'];
                    $postData['alipay_orderid'] = $order_id;
                    $postData['reason'] = 'success';
                    $postData['url'] = $daifuSetting['async_url'];
                    queue_push(new PaymentResultNoticeJob($postData));
                }
                $logData['title'] = '代付功能(平台)';
                $logData['uid'] = (int) $this->params['uid'];
                $logData['ip'] = $this->params['ip'];
                $logData['username'] = $this->params['username'];
                $logData['opstatus'] = $feeStatus;
                $feeStatus = ($feeStatus == 1) ? '成功' : '失败';
                $logData['extlog'] = '通过代付API提交了' . $this->params['money'] . '元代付，支付后余额：' . round($pay_yue, 2) . '元，收款人：' . $this->params['realname'] . '(' . $this->params['alipay'] . ')，手续费：' . $daifuFee . '元，支付宝流水号：' . $order_id . '，扣款状态：' . $feeStatus;
                addOperateLog($logData);
            } else {
                Db::rollBack();
                $updatePayData['status'] = -1;
                $updatePayData['daifued_yue'] = $pay_yue;
                $updatePayData['statusmsg'] = (!empty($result->$responseNode->sub_msg)) ? $result->$responseNode->sub_msg : json_encode($result->$responseNode);
                mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $updatePayData);
                if (!empty($daifuSetting['async_url'])) {
                    $postData['thirdorder'] = $this->params['thirdorder'];
                    $postData['orderId'] = $this->params['orderId'];
                    $postData['alipay_orderid'] = '';
                    $postData['reason'] = $updatePayData['statusmsg'];
                    $postData['url'] = $daifuSetting['async_url'];
                    queue_push(new PaymentResultNoticeJob($postData));
                }
                $msg = '代付失败，请检查传入数据是否正确: ' . json_encode($result->$responseNode);
                $logData['title'] = '代付功能(平台)';
                $logData['uid'] = (int) $this->params['uid'];
                $logData['ip'] = $this->params['ip'];
                $logData['username'] = $this->params['username'];
                $logData['extlog'] = '通过代付API提交了' . $this->params['money'] . '元代付，收款人：' . $this->params['realname'] . '(' . $this->params['alipay'] . ')，手续费：' . $daifuFee . '元，失败日志：' . json_encode($result->$responseNode);
                addOperateLog($logData);
            }
        }
    }
    public function notice($msg)
    {
        $cacheData['async_status'] = -1;
        $cacheData['status'] = -1;
        $cacheData['statusmsg'] = $msg;
        $cacheData['alipay_orderid'] = '';
        $cacheData['daifu_fee'] = '';
        $cacheData['daifued_yue'] = '';
        mongodb()->updateRow('df_trade_orders', ['_id' => $this->params['orderId']], $cacheData);
        if (!empty($daifuSetting['async_url'])) {
            // $postData['event'] = 'PAYMENT_FAIL';
            $postData['thirdorder'] = $this->params['thirdorder'];
            $postData['orderId'] = $this->params['orderId'];
            $postData['alipay_orderid'] = '';
            $postData['reason'] = $cacheData['statusmsg'];
            $postData['url'] = $daifuSetting['async_url'];
            queue_push(new PaymentResultNoticeJob($postData));
        }
        throw new NullReturnException;
    }
}
